package sv.gob.mh.dgii.service.rc;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.beanutils.DynaBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.ObjectRetrievalFailureException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import sv.gob.mh.dgii.common.Utils;
import sv.gob.mh.dgii.dao.hibernate.Dao;
import sv.gob.mh.dgii.dao.rc.RcRucDao;
import sv.gob.mh.dgii.model.ImSolicitud;
import sv.gob.mh.dgii.model.RcRuc;
import sv.gob.mh.dgii.service.BaseService;

@Service
@Transactional(readOnly = true, propagation = Propagation.REQUIRED)
public class RcRucServiceImpl extends BaseService implements
        RcRucService {

    @Autowired
    private RcRucDao rcRucDao;
    @Autowired
    private RcRucRiskService rcRucRiskService;

    public DynaBean getInfoTarjetaNit(String nit) {
        return rcRucDao.getInfoTarjetaNit(nit);
    }

    public DynaBean getInfoTarjetaNrc(String nit) {
        return rcRucDao.getInfoTarjetaNrc(nit);
    }

    public void activateContributor(String nit) {
        activeContributor(nit, "A");
    }

    public void deactivateContributor(String nit) {
        activeContributor(nit, "I");
    }

    public void activeContributor(String nit, String status) {
        RcRuc rc = new RcRuc();
        rc.setNit(nit);
        rc = (RcRuc) rcRucDao.findByKey(rc);
        rc.setBactivo(status);
        rcRucDao.save(rc);
    }

    public Dao getDao() {
        return rcRucDao;
    }

    public RcRuc findByNit(String nit) {
        try {
            /*RcRuc rc = new RcRuc();
             rc.setNit(nit);
             Object obj = rcRucDao.findByKey(rc);*/
            return rcRucDao.findByNit(nit);
        } catch (ObjectRetrievalFailureException ore) {
            return null;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public List findByTipoContrib(RcRuc contributor) {
        return rcRucDao.getByTipoContrib(contributor);
    }

    /**
     * si es el salvador(9300) nit = [departamento] + [municipio] + [[dia] +
     * [mes] + [a�o]] si no nit = [pais] + [[dia] + [mes] + [a�o]]
     *
     * nit+= [correlativo] + [digitoChequeo]
     */
    public String getNit(RcRuc contrib) {

        String formatoNit = "ddMMyy";
        String formattedDate = Utils.getFormattedDate(contrib.getFnacConst(),
                formatoNit);
        String nit;
        String cntCode = contrib.getTbPais().getCpais();
        if (!cntCode.equals(EL_SALVADOR)) {
            nit = cntCode;
        } else {
            nit = contrib.getTbMunicipio().getId().getCdepartamento()
                    + contrib.getTbMunicipio().getId().getCmunicipio();
        }
        nit += formattedDate;
        // dando el tamanho adecuado al correlativo
        String correlativo = "" + getCorrelativo(nit);
        // Esto esta de mas porque siempre devolvera digitos de 3 cifras.
        // correlativo = GeneralUtils.lpadS(correlativo, "0", 3);
        nit += correlativo;
        String dchequeo = "" + getDigitoChequeo(nit);
        nit += dchequeo;
        return nit;
    }

    public int getCorrelativo(String nitRaiz) {
        Integer correl = rcRucDao.getNextCorrelativo(nitRaiz);
        if (correl == null) {
            return 0;
        }
        return correl.intValue();
    }

    public long getDigitoChequeo(String nitRaiz) {
        try {
            Integer digito = rcRucDao.getDigitoChequeo(nitRaiz, RcRucDao.NIT);
            return digito.longValue();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    
    public String getRiesgo(RcRuc contrib, List<RcRuc> contList) {
        String riesgo = "I";
        if (rcRucRiskService.isHighRisk(contrib, contList)) {
            riesgo = "A";
        }/*
         * else{ if(riskServ.isMediumRisk(contrib, contList)){ riesgo = "M"; } }
         */
        return riesgo;
    }

    public List<RcRuc> fillRiesgos(List<RcRuc> contList) {
        List<RcRuc> lst = new ArrayList<RcRuc>(0);
        List<RcRuc> result = new ArrayList<RcRuc>(0);
        lst.addAll(contList);
        String risk = "";
        for (RcRuc contributor : lst) {
            risk = getRiesgo(contributor, contList);
            contributor.setRisk(risk);
            result.add(contributor);
        }
        return result;
    }

    public boolean validateContributor(String nit) {
        boolean valid = true;
        try {
            RcRuc contrib = new RcRuc();
            contrib.setNit(nit);
            findByKey(contrib);
        } catch (Exception e) {
            valid = false;
        }

        return valid;
    }

    public String getDireccion(String nit, String tipoDireccion)
            throws Exception {
        return rcRucDao.getDireccion(nit, tipoDireccion);
    }

    public String getCaracterTributario(String nit, String tipoCaracter)
            throws Exception {
        return rcRucDao.getCaracterTributario(nit, tipoCaracter);
    }

    public String getFechaIngreso(String nit) throws Exception {
        return rcRucDao.getFechaIngreso(nit);
    }

    public String getRepresentante(String nit) throws Exception {
        return rcRucDao.getRepresentante(nit);
    }

    public void termino(Object[] params) throws SQLException {
        rcRucDao.termino(params);
    }

    public List getRiskList(RcRuc contrib) {
        String snombres = null;
        String s1apeRasoc = null;
        String s2apeAbrev = null;
        String cclase = null;
        if (!Utils.isNullOrEmpty(contrib.getTbTipoContrib())) {
            cclase = contrib.getTbTipoContrib().getId().getCclase();
        }
        if (!Utils.isNullOrEmpty(contrib.getSnombres())) {
            snombres = contrib.getSnombres().toUpperCase().trim();
        }
        if (!Utils.isNullOrEmpty(contrib.getS1apeRasoc())) {
            s1apeRasoc = contrib.getS1apeRasoc().toUpperCase().trim();
        }
        if (!Utils.isNullOrEmpty(contrib.getS2apeAbrev())) {
            s2apeAbrev = contrib.getS2apeAbrev().toUpperCase().trim();
        }
        return rcRucDao.getRiskList(snombres, s1apeRasoc,
                s2apeAbrev, cclase);
    }

    public String findNombreByNit(String nit) {
        String name;
        try {
            name = rcRucDao.getNombre(nit);
        } catch (Exception e) {
            name = "";
        }
        return name;
    }

    public boolean isNitInscrito(String nit, Date periodo) {
        return rcRucDao.isNitInscrito(nit, periodo);
    }

    public List<DynaBean> findVehiculos(String nit) {
        return rcRucDao.findVehiculos(nit);
    }

    public List<DynaBean> findBienesRaices(String nit) {
        return rcRucDao.findBienesRaices(nit);
    }

    public List<DynaBean> findCasoxTecnico(String nit, String nit2) {
        return rcRucDao.findCasoxTecnico(nit, nit2);
    }

    public List<DynaBean> findCasos(String nit, String anio) {
        return rcRucDao.findCasos(nit, anio);
    }

    public List<DynaBean> findAduanasImportaciones(String nit, String fini, String ffin) {
        return rcRucDao.findAduanasImportaciones(nit, fini, ffin);
    }

    public List<DynaBean> findAduanasInternaciones(String nit, String fini, String ffin) {
        return rcRucDao.findAduanasInternaciones(nit, fini, ffin);
    }

    public List<DynaBean> findAduanasExportaciones(String nit, String fini, String ffin) {
        return rcRucDao.findAduanasExportaciones(nit, fini, ffin);
    }

    public List<DynaBean> findAduanasReexportaciones(String nit, String fini, String ffin) {
        return rcRucDao.findAduanasReexportaciones(nit, fini, ffin);
    }

    public List<DynaBean> findCasoxSupervisor(String nitUsuario, String key,
            String tipo) {
        return rcRucDao.findCasoxSupervisor(nitUsuario, key, tipo);
    }

    public List<DynaBean> findUnixTec(String nitUsuario) {
        return rcRucDao.findUnixTec(nitUsuario);
    }

    public boolean isBienestar(String nit) {
        return rcRucDao.isBienestar(nit);
    }

    public boolean isIpsfa(String nit) {
        return rcRucDao.isIpsfa(nit);
    }

    @Override
    public RcRuc findRepresentanteDeImSolicitud(ImSolicitud imSolicitud) {
        return rcRucDao.findRepresentanteDeImSolicitud(imSolicitud);
    }

    @Override
    public RcRuc findPropietarioDeImSolicitud(ImSolicitud imSolicitud) {
        return rcRucDao.findPropietarioDeImSolicitud(imSolicitud);
    }
}// class